package com.wuwei.elearning.question.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wuwei.elearning.exception.ElearningMysqlException;
import com.wuwei.elearning.question.domain.*;
import com.wuwei.elearning.question.mapper.*;
import com.wuwei.elearning.question.service.SubjectTestService;
import com.wuwei.elearning.question.vo.SubjectTestCountVO;
import com.wuwei.elearning.question.vo.SubjectTestVo;
import com.wuwei.elearning.setting.domain.User;
import com.wuwei.elearning.setting.mapper.UserMapper;
import com.wuwei.elearning.utils.TimeUtils;
import com.wuwei.elearning.utils.result.Result;
import com.wuwei.elearning.utils.token.TokenUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 课后考试表 前端控制器
 * </p>
 *
 * @author wuwei
 * @since 2025-03-12
 */
@RestController
@RequestMapping("/elearning/subjectTest")
@CrossOrigin
public class SubjectTestController {

    @Resource
    private SubjectTestService subjectTestService;


    @Resource
    private SubjectTestMapper subjectTestMapper;
    @Autowired
    private SubjectMapper subjectMapper;
    @Autowired
    private UserRelationSubjectMapper userRelationSubjectMapper;
    @Autowired
    private UserMapper userMapper;

    @PutMapping("insert/{name}/{subjectId}/{number}/{subjectName}")
    public Result<Long> insert(HttpServletRequest request, @PathVariable("name") String name,
                               @PathVariable("subjectId") Long subjectId,
                               @PathVariable("number") Integer number,@PathVariable("subjectName") String subjectName) {
        Subject subject = subjectMapper.selectById(subjectId);
        if (subject.getNeedTest()==0) {
            throw new ElearningMysqlException(30045,"该课程不允许进行考试！");
        }
        String token = request.getHeader("Authorization");
        Long account = TokenUtil.getAccountFromToken(token);
        Long SubjectTestId =  subjectTestService.insert(name,subjectId,number,account,subjectName);
        return Result.ok(SubjectTestId);
    }

    @PutMapping("/submit/{score}/{subjectTestId}/{usedTime}/{timestamp}")
    public Result<String> submit(
            @PathVariable("score") Integer score,
            @PathVariable("subjectTestId") Long subjectTestId,
            @PathVariable("usedTime") Integer usedTime,
            @PathVariable("timestamp") Long timestamp
    ) {
        String res = subjectTestService.submit(score,subjectTestId,usedTime,timestamp);
        if ("考试通过".equals(res)) {
            return Result.ok(res);
        } else {
            return Result.fail(res);
        }
    }

    /**
     * 根据account和subjectId获取subjectTest表中tested为1的数量
     * 获取考试的最高分，即获取subjectTest表中查询结果的max(score)
     * @param subjectId
     * @return
     */
    @GetMapping("getTestedCountAndScore/{subjectId}")
    public Result<SubjectTestCountVO> getRemainCount(@PathVariable("subjectId") Long subjectId, HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        Long account = TokenUtil.getAccountFromToken(token);

        LambdaQueryWrapper<SubjectTest> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SubjectTest::getSubjectId, subjectId)
                .eq(SubjectTest::getAccount, account)
                .eq(SubjectTest::getTested, 1);

        Long count = subjectTestMapper.selectCount(wrapper);

        // 初始化返回对象
        SubjectTestCountVO subjectTestCountVO = new SubjectTestCountVO();
        subjectTestCountVO.setTestedCount(count);

        // 只有在有考试记录时才获取最高分
        if (count > 0) {
            SubjectTest highestScore = subjectTestMapper.selectOne(
                    new LambdaQueryWrapper<SubjectTest>()
                            .select(SubjectTest::getScore)
                            .eq(SubjectTest::getSubjectId, subjectId)
                            .eq(SubjectTest::getAccount, account)
                            .eq(SubjectTest::getTested, 1)
                            .orderByDesc(SubjectTest::getScore)
                            .last("LIMIT 1")
            );

            if (highestScore != null) {
                subjectTestCountVO.setMaxScore(highestScore.getScore());
            } else {
                subjectTestCountVO.setMaxScore(0); // 或者设置为其他默认值
            }
        } else {
            subjectTestCountVO.setMaxScore(0); // 如果没有考试记录，设置默认分数
        }

        return Result.ok(subjectTestCountVO);
    }

    /**
     * 获取已经考试的人员的最高分
     * 获取没有考试的人员
     * @param subjectId
     * @return
     */
    @GetMapping("getBySubjectId/{subjectId}")
    public Result<SubjectTestVo> getBySubjectId(@PathVariable("subjectId") Long subjectId) {
        List<SubjectTest> subjectTests = subjectTestMapper
                .selectList(new LambdaQueryWrapper<SubjectTest>()
                        .eq(SubjectTest::getTested,1)
                        .eq(SubjectTest::getSubjectId, subjectId)
                        .orderByDesc(SubjectTest::getScore)
                        .last("LIMIT 1")
                );

        List<UserRelationSubject> userRelationSubjects = userRelationSubjectMapper.selectList(
                new LambdaQueryWrapper<UserRelationSubject>()
                        .eq(UserRelationSubject::getSubjectId, subjectId)
        );
        List<Long> accounts = userRelationSubjects.stream().map(UserRelationSubject::getAccount).collect(Collectors.toList());
        if (accounts.isEmpty()) {
            return Result.ok(null);
        }
        //所有需要考试的人员名称
        List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getAccount, accounts));
        //已经考试过的人员名称
        List<Long> testedAccounts = subjectTests.stream().map(SubjectTest::getAccount).collect(Collectors.toList());
        //从user里去除掉testedAccounts，如果user的account在testedAccounts里面，则将其去除，得到没有考试的人员
        List<String> names = users.stream()
                .filter(user -> !testedAccounts.contains(user.getAccount()))
                .map(User::getName).collect(Collectors.toList());


        SubjectTestVo subjectTestVo = new SubjectTestVo();
        subjectTestVo.setSubjectTests(subjectTests);
        subjectTestVo.setNames(names);
        return Result.ok(subjectTestVo);
    }

    @GetMapping("getPassedList")
    public Result<List<SubjectTest>> getPassedList(@RequestParam("pageSize") Integer pageSize,@RequestParam("currentPage") Integer currentPage,
                                               @RequestParam("startTime") Long startTime,@RequestParam("endTime") Long endTime,
                                               @RequestParam("name")String name,HttpServletRequest request
    ) {
        LocalDateTime start_time = TimeUtils.getStartLocalTime(startTime);
        LocalDateTime end_time = TimeUtils.getEndLocalTime(endTime);
        String token = request.getHeader("Authorization");
        Long account = TokenUtil.getAccountFromToken(token);
        LambdaQueryWrapper<SubjectTest> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SubjectTest::getAccount, account)
                .like(SubjectTest::getSubjectName, name)
                .ge(SubjectTest::getEndTime, start_time)
                .le(SubjectTest::getEndTime, end_time)
                .eq(SubjectTest::getTested, 1)
                .eq(SubjectTest::getPassed,1)
                .orderByDesc(SubjectTest::getEndTime);
        IPage<SubjectTest> page = new Page();
        page.setCurrent(currentPage);
        page.setSize(pageSize);
        IPage<SubjectTest> subjectTestIPage = subjectTestMapper.selectPage(page, wrapper);
        List<SubjectTest> records = subjectTestIPage.getRecords();
        return Result.ok(records);
    }



    @GetMapping("getPassedCount")
    public Result<Long> getPassedCount(@RequestParam("startTime") Long startTime,@RequestParam("endTime") Long endTime,
                                               @RequestParam("name")String name,HttpServletRequest request) {
        LocalDateTime start_time = TimeUtils.getStartLocalTime(startTime);
        LocalDateTime end_time = TimeUtils.getEndLocalTime(endTime);
        String token = request.getHeader("Authorization");
        Long account = TokenUtil.getAccountFromToken(token);
        LambdaQueryWrapper<SubjectTest> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SubjectTest::getAccount, account)
                .like(SubjectTest::getSubjectName, name)
                .ge(SubjectTest::getEndTime, start_time)
                .le(SubjectTest::getEndTime, end_time)
                .eq(SubjectTest::getTested, 1)
                .eq(SubjectTest::getPassed,1)
                .orderByDesc(SubjectTest::getEndTime);
        Long count = subjectTestMapper.selectCount(wrapper);
        return Result.ok(count);
    }


}

